﻿using Asxsyd92Core.Utils;
using Asxsyd92Core.Utils.Provider;
using System;
using System.Collections.Generic;
using System.Linq;
using WebOS.Dal;
using WebOS.Modle.WorkFlowInstalledSub;
namespace WebOS.Bll
{
    public class WorkFlowBll
    {
        public static WorkFlowBll Instance
        {
            get { return SingletonProvider<WorkFlowBll>.Instance; }
        }

        public string WorkFlowList(string title, Guid type, Guid user, DateTime date1, DateTime date2, int page, int limit)
        {
            string counts = "(select count(1) from WorkFlow where  CreateUserID='" + user + "' ";
            string sqls = "", f = "";
            string sql = "";
            if (type != null && type != Guid.Empty)
            {

                sql = sql + "  and Type= '" + type + "'";
                counts = counts + "  and Type ='" + type + "'";
                f = f + "  and Type ='" + type + "'";
            }
            if (title != "" && title != null)
            {
                title = "'%" + title + "%'";
                sql = sql + " and Name like " + title;
                counts = counts + " and Name like " + title;
                f = f + " and Name like " + title;
            }

            //降序
            sql = sql + "and RowNumber > " + limit + " * (" + page + " - 1)";
            //分页
            var fy = "(SELECT ROW_NUMBER() OVER(ORDER BY id DESC) AS RowNumber,*FROM WorkFlow where  CreateUserID='" + user + "' " + f + ")";
            sqls = "select top " + limit + "  *," + counts + ") as Count  from " + fy + " as A where  CreateUserID='" + user + "' " + sql;
            var da = WorkFlowDal.Instance.GetList(sqls, new { }).ToList();

            return JSONhelper.ToJson(new { code = 0, msg = "", count = da.Count == 0 ? 0 : da.First().Count, data = da }, false);
        }
        /// <summary>
        /// 安装一个流程
        /// </summary>
        /// <param name="jsonString"></param>
        /// <param name="isMvc">是否是mvc程序，用于区分应用程序库连接</param>
        /// <returns>返回1 表示成功 其它为具体错误信息</returns>
        public string Install(string jsonString, Guid user, bool isMvc = true)
        {
            string saveInfo = Seve(jsonString, user);
            if ("保存成功" != saveInfo)
            {
                return saveInfo;
            }
            string errMsg;

            WebOS.Modle.WorkFlowInstalled wfInstalled = GetWorkFlowRunModel(jsonString, out errMsg);
            if (wfInstalled == null)
            {
                return errMsg;
            }
            else
            {
                WebOS.Modle.WorkFlow wf = WorkFlowDal.Instance.Get(wfInstalled.ID);
                if (wf == null)
                {
                    return "流程实体为空";
                }
                else
                {
                    using (System.Transactions.TransactionScope scope = new System.Transactions.TransactionScope())
                    {
                        wf.InstallDate = wfInstalled.InstallTime;
                        wf.InstallUserID = wfInstalled.InstallUser.ToGuid();
                        wf.RunJSON = wfInstalled.RunJSON;
                        wf.Status = 2;
                        WorkFlowDal.Instance.Update(wf);

                        wfInstalled.Status = 2;

                        #region 添加到应用程序库
                        Modle.AppLibrary bappLibrary = new Modle.AppLibrary();
                        WebOS.Modle.AppLibrary app = AppLibraryDal.Instance.Get(new { Code = wfInstalled.ID.ToString() });
                        bool isAdd = false;
                        if (app == null)
                        {
                            isAdd = true;
                            app = new WebOS.Modle.AppLibrary();
                            app.ID = Guid.NewGuid();
                        }
                        app.Address = isMvc ? "WorkFlowRun/Index" : "Platform/WorkFlowRun/Default.aspx";
                        app.Code = wfInstalled.ID.ToString();
                        app.Note = "流程应用";
                        app.OpenMode = 0;
                        app.Params = "flowid=" + wfInstalled.ID.ToString();
                        app.Title = wfInstalled.Name;
                        app.Type = wfInstalled.Type.IsGuid() ? wfInstalled.Type.ToGuid() : DictionaryDal.Instance.Get(new { Code = "FlowTypes" }).ID;//.GetIDByCode("");
                        if (isAdd)
                        {
                            AppLibraryDal.Instance.Insert(app);
                        }
                        else
                        {
                            AppLibraryDal.Instance.Update(app);
                        }


                        #endregion

                        return "安装成功";
                    }
                }
            }

        }

        public string Seve(string json, Guid user)
        {
            var jsonData = LitJSONCore.JsonMapper.ToObject(json);
            string id = jsonData["id"].ToString();
            string name = jsonData["name"].ToString();
            string type = jsonData["type"].ToString();
            Guid flowID;
            if (id == Guid.Empty.ToString())
            {
                return "请先新建或打开流程!";
            }
            else if (string.IsNullOrEmpty(name))
            {
                return "流程名称不能为空!";
            }
            else
            {
                Guid.TryParse(id, out flowID);
                Modle.WorkFlow bwf = new Modle.WorkFlow();
                Modle.WorkFlow wf = WorkFlowDal.Instance.Get(flowID);
                bool isAdd = false;
                if (wf == null)
                {
                    wf = new Modle.WorkFlow();
                    isAdd = true;
                    wf.ID = flowID;
                    wf.CreateDate = System.DateTime.Now;
                    wf.CreateUserID = user;
                    wf.Status = 1;
                }
                wf.DesignJSON = json;
                wf.InstanceManager = jsonData["instanceManager"].ToString();
                wf.Manager = jsonData["manager"].ToString();
                wf.Name = name.Trim();
                // wf.Type = type.IsGuid() ? type.ToGuid() : new DictionaryDal.().GetIDByCode("FlowTypes");
                try
                {
                    if (isAdd)
                    {
                        if (WorkFlowDal.Instance.Insert(wf) > 0) return "保存成功";
                    }
                    else
                    {
                        if (WorkFlowDal.Instance.Update(wf) > 0) return "保存成功";
                    }
                    return "保存失败";
                }
                catch (Exception err)
                {
                    return err.Message;
                }
            }
        }

        public string GetJSON(Guid flowid, string type)
        {
            var da = WorkFlowDal.Instance.GetWhere(new { ID = flowid }).FirstOrDefault();
            if (da != null)
            {
                return "0" == type ? da.RunJSON : da.DesignJSON;
            }
            else
            { return "{}"; }
        }


        /// <summary>
        /// 得到一个流程运行时实体
        /// </summary>
        /// <param name="jsonString">流程设计json字符串</param>
        /// <returns>流程已安装实体类(如果返回为空则表示验证失败,流程设计不完整)</returns>
        public Modle.WorkFlowInstalled GetWorkFlowRunModel(string jsonString, out string errMsg)
        {
            errMsg = "";
            WebOS.Modle.WorkFlowInstalled wfInstalled = new WebOS.Modle.WorkFlowInstalled();
            var json = LitJSONCore.JsonMapper.ToObject(jsonString);

            #region 载入基本信息
            string id = json["id"].ToString();
            if (!id.IsGuid())
            {
                errMsg = "流程ID错误";
                return null;
            }
            else
            {
                wfInstalled.ID = id.ToGuid();
            }

            string name = json["name"].ToString();
            if (name.IsNullOrEmpty())
            {
                errMsg = "流程名称为空";
                return null;
            }
            else
            {
                wfInstalled.Name = name.Trim();
            }

            string type = json["type"].ToString();
            wfInstalled.Type = type.IsNullOrEmpty() ? DictionaryDal.Instance.Get(new { Code = "FlowTypes" }).ToString() : type.Trim();

            string manager = json["manager"].ToString();
            if (manager.IsNullOrEmpty())
            {
                errMsg = "流程管理者为空";
                return null;
            }
            else
            {
                wfInstalled.Manager = manager;
            }

            string instanceManager = json["instanceManager"].ToString();
            if (instanceManager.IsNullOrEmpty())
            {
                errMsg = "流程实例管理者为空";
                return null;
            }
            else
            {
                wfInstalled.Manager = instanceManager;
            }

            wfInstalled.RemoveCompleted = json["removeCompleted"].ToString().ToInt();
            wfInstalled.Debug = json["debug"].ToString().ToInt();
            wfInstalled.DebugUsers = OrganizeBll.Instance.GetAllUsers(json["debugUsers"].ToString());
            wfInstalled.Note = json["note"].ToString();
            wfInstalled.FlowType = json.ContainsKey("flowType") ? json["flowType"].ToString().ToInt() : 0;

            List<Modle.WorkFlowInstalledSub.DataBases> dataBases = new List<Modle.WorkFlowInstalledSub.DataBases>();
            var dbs = json["databases"];
            if (dbs.IsArray)
            {
                foreach (LitJSONCore.JsonData db in dbs)
                {
                    dataBases.Add(new WebOS.Modle.WorkFlowInstalledSub.DataBases()
                    {
                        LinkID = db["link"].ToString().ToGuid(),
                        LinkName = db["linkName"].ToString(),
                        Table = db["table"].ToString(),
                        PrimaryKey = db["primaryKey"].ToString()
                    });
                }
            }
            wfInstalled.DataBases = dataBases;

            var titleField = json["titleField"];
            if (titleField.IsObject)
            {
                wfInstalled.TitleField = new WebOS.Modle.WorkFlowInstalledSub.TitleField()
                {
                    Field = titleField["field"].ToString(),
                    LinkID = titleField["link"].ToString().ToGuid(),
                    LinkName = "",
                    Table = titleField["table"].ToString()
                };
            }
            #endregion

            #region 载入步骤信息
            List<Modle.WorkFlowInstalledSub.Step> stepsList = new List<Modle.WorkFlowInstalledSub.Step>();
            LitJSONCore.JsonData steps = json["steps"];
            if (steps.IsArray)
            {
                foreach (LitJSONCore.JsonData step in steps)
                {
                    #region 行为
                    LitJSONCore.JsonData behavior = step["behavior"];
                    WebOS.Modle.WorkFlowInstalledSub.StepSet.Behavior behavior1 = new WebOS.Modle.WorkFlowInstalledSub.StepSet.Behavior();
                    if (behavior.IsObject)
                    {
                        behavior1.BackModel = behavior["backModel"].ToString().ToInt();
                        behavior1.BackStepID = behavior["backStep"].ToString().ToGuid();
                        behavior1.BackType = behavior["backType"].ToString().ToInt();
                        behavior1.DefaultHandler = behavior["defaultHandler"].ToString();
                        behavior1.FlowType = behavior["flowType"].ToString().ToInt();
                        behavior1.HandlerStepID = behavior["handlerStep"].ToString().ToGuid();
                        behavior1.HandlerType = behavior["handlerType"].ToString().ToInt();
                        behavior1.HanlderModel = behavior["hanlderModel"].ToString().ToInt(3);
                        behavior1.Percentage = behavior["percentage"].ToString().IsDecimal() ? behavior["percentage"].ToString().ToDecimal() : decimal.MinusOne;
                        behavior1.RunSelect = behavior["runSelect"].ToString().ToInt();
                        behavior1.SelectRange = behavior["selectRange"].ToString();
                        behavior1.ValueField = behavior["valueField"].ToString();
                        behavior1.Countersignature = behavior.ContainsKey("countersignature") ? behavior["countersignature"].ToString().ToInt() : 0;
                        behavior1.CountersignaturePercentage = behavior.ContainsKey("countersignaturePercentage") ? behavior["countersignaturePercentage"].ToString().ToDecimal() : decimal.MinusOne;
                        behavior1.SubFlowStrategy = behavior.ContainsKey("subflowstrategy") ? behavior["subflowstrategy"].ToString().ToInt() : int.MinValue;
                        behavior1.CopyFor = behavior.ContainsKey("copyFor") ? behavior["copyFor"].ToString() : "";
                    }
                    #endregion
                    #region 按钮
                    LitJSONCore.JsonData buttons = step["buttons"];
                    List<Modle.WorkFlowInstalledSub.StepSet.Button> buttionList = new List<Modle.WorkFlowInstalledSub.StepSet.Button>();
                    if (buttons.IsArray)
                    {
                        foreach (LitJSONCore.JsonData button in buttons)
                        {
                            string butID = button["id"].ToString();
                            if (butID.IsGuid())
                            {
                                var buttonModel = WorkFlowButtonsDal.Instance.Get(butID.ToGuid());
                                if (buttonModel == null)
                                {
                                    continue;
                                }
                                buttionList.Add(new WebOS.Modle.WorkFlowInstalledSub.StepSet.Button()
                                {
                                    ID = butID,
                                    Note = buttonModel.Note.IsNullOrEmpty() ? "" : buttonModel.Note.Replace("\"", "'"),
                                    Sort = button["sort"].ToString().ToInt()
                                });
                            }
                            else
                            {
                                buttionList.Add(new WebOS.Modle.WorkFlowInstalledSub.StepSet.Button()
                                {
                                    ID = butID,
                                    Note = "",
                                    Sort = button["sort"].ToString().ToInt()
                                });
                            }
                        }
                    }
                    if (buttionList.Count == 0)
                    {
                        errMsg = string.Format("步骤[{0}]未设置按钮", step["name"].ToString());
                        return null;
                    }
                    #endregion
                    #region 事件
                    LitJSONCore.JsonData event1 = step["event"];
                    WebOS.Modle.WorkFlowInstalledSub.StepSet.Event event2 = new WebOS.Modle.WorkFlowInstalledSub.StepSet.Event();
                    if (event1.IsObject)
                    {
                        event2.BackAfter = event1["backAfter"].ToString();
                        event2.BackBefore = event1["backBefore"].ToString();
                        event2.SubmitAfter = event1["submitAfter"].ToString();
                        event2.SubmitBefore = event1["submitBefore"].ToString();
                        event2.SubFlowActivationBefore = event1.ContainsKey("subflowActivationBefore") ? event1["subflowActivationBefore"].ToString() : "";
                        event2.SubFlowCompletedBefore = event1.ContainsKey("subflowCompletedBefore") ? event1["subflowCompletedBefore"].ToString() : "";
                    }
                    #endregion
                    #region 表单
                    LitJSONCore.JsonData forms = step["forms"];
                    List<Modle.WorkFlowInstalledSub.StepSet.Form> formList = new List<Modle.WorkFlowInstalledSub.StepSet.Form>();
                    if (forms.IsArray)
                    {
                        foreach (LitJSONCore.JsonData form in forms)
                        {
                            formList.Add(new WebOS.Modle.WorkFlowInstalledSub.StepSet.Form()
                            {
                                ID = form["id"].ToString().ToGuid(),
                                Name = form["name"].ToString(),
                                Sort = form["srot"].ToString().ToInt()
                            });
                        }
                    }
                    if (formList.Count == 0)
                    {
                        errMsg = string.Format("步骤[{0}]未设置表单", step["name"].ToString());
                        return null;
                    }
                    #endregion
                    #region 字段状态
                    LitJSONCore.JsonData fieldStatus = step["fieldStatus"];
                    List<Modle.WorkFlowInstalledSub.StepSet.FieldStatus> fieldStatusList = new List<Modle.WorkFlowInstalledSub.StepSet.FieldStatus>();
                    if (fieldStatus.IsArray)
                    {
                        foreach (LitJSONCore.JsonData field in fieldStatus)
                        {
                            fieldStatusList.Add(new WebOS.Modle.WorkFlowInstalledSub.StepSet.FieldStatus()
                            {
                                Check = field["check"].ToString().ToInt(),
                                Field = field["field"].ToString(),
                                Status1 = field["status"].ToString().ToInt()
                            });
                        }
                    }
                    #endregion
                    #region 坐标/基本信息
                    LitJSONCore.JsonData position = step["position"];
                    decimal x = 0, y = 0;
                    if (position.IsObject)
                    {
                        x = position["x"].ToString().ToDecimal();
                        y = position["y"].ToString().ToDecimal();
                    }

                    stepsList.Add(new WebOS.Modle.WorkFlowInstalledSub.Step()
                    {
                        Archives = step["archives"].ToString().ToInt(),
                        ArchivesParams = step["archivesParams"].ToString(),
                        Behavior = behavior1,
                        Buttons = buttionList,
                        Event = event2,
                        ExpiredPrompt = step["expiredPrompt"].ToString().ToInt(),
                        Forms = formList,
                        FieldStatus = fieldStatusList,
                        ID = step["id"].ToString().ToGuid(),
                        Type = step.ContainsKey("type") ? step["type"].ToString() : "normal",
                        LimitTime = step["limitTime"].ToString().ToDecimal(),
                        Name = step["name"].ToString(),
                        Note = step["note"].ToString(),
                        OpinionDisplay = step["opinionDisplay"].ToString().ToInt(),
                        OtherTime = step["otherTime"].ToString().ToDecimal(),
                        SignatureType = step["signatureType"].ToString().ToInt(),
                        WorkTime = step["workTime"].ToString().ToDecimal(),
                        SubFlowID = step.ContainsKey("subflow") ? step["subflow"].ToString() : "",
                        Position_x = x,
                        Position_y = y
                    });
                    #endregion

                }
            }

            if (1 == wfInstalled.FlowType)
            {

            }

            wfInstalled.Steps = stepsList;
            if (stepsList.Count == 0)
            {
                errMsg = "流程至少需要一个步骤";
                return null;
            }
            #endregion

            #region 载入连线信息

            List<Modle.WorkFlowInstalledSub.Line> linesList = new List<Modle.WorkFlowInstalledSub.Line>();
            LitJSONCore.JsonData lines = json.ContainsKey("lines") ? json["lines"] : null;
            if (lines != null && lines.IsArray)
            {
                foreach (LitJSONCore.JsonData line in lines)
                {
                    linesList.Add(new WebOS.Modle.WorkFlowInstalledSub.Line()
                    {
                        ID = line["id"].ToString().ToGuid(),
                        FromID = line["from"].ToString().ToGuid(),
                        ToID = line["to"].ToString().ToGuid(),
                        CustomMethod = line["customMethod"].ToString(),
                        SqlWhere = line["sql"].ToString(),
                        NoAccordMsg = line.ContainsKey("noaccordMsg") ? line["noaccordMsg"].ToString() : "",
                        //Organize_SenderIn = line.ContainsKey("organize_senderin") ? line["organize_senderin"].ToString() : "",
                        //Organize_SenderNotIn = line.ContainsKey("organize_sendernotin") ? line["organize_sendernotin"].ToString() : "",
                        //Organize_SponsorIn = line.ContainsKey("organize_sponsorin") ? line["organize_sponsorin"].ToString() : "",
                        //Organize_SponsorNotIn = line.ContainsKey("organize_sponsornotin") ? line["organize_sponsornotin"].ToString() : "",
                        //Organize_SenderLeader = line.ContainsKey("organize_senderleader") ? line["organize_senderleader"].ToString() : "",
                        //Organize_SenderChargeLeader = line.ContainsKey("organize_senderchargeleader") ? line["organize_senderchargeleader"].ToString() : "",
                        //Organize_SponsorLeader = line.ContainsKey("organize_sponsorleader") ? line["organize_sponsorleader"].ToString() : "",
                        //Organize_SponsorChargeLeader = line.ContainsKey("organize_sponsorchargeleader") ? line["organize_sponsorchargeleader"].ToString() : "",
                        //Organize_NotSenderLeader = line.ContainsKey("organize_notsenderleader") ? line["organize_notsenderleader"].ToString() : "",
                        //Organize_NotSenderChargeLeader = line.ContainsKey("organize_notsenderchargeleader") ? line["organize_notsenderchargeleader"].ToString() : "",
                        //Organize_NotSponsorLeader = line.ContainsKey("organize_notsponsorleader") ? line["organize_notsponsorleader"].ToString() : "",
                        //Organize_NotSponsorChargeLeader = line.ContainsKey("organize_notsponsorchargeleader") ? line["organize_notsponsorchargeleader"].ToString() : ""
                    });
                }
            }

            wfInstalled.Lines = linesList;

            #endregion

            #region 载入其它信息
            //得到第一步
            List<Guid> firstStepIDList = new List<Guid>();
            foreach (var step in wfInstalled.Steps)
            {
                if (wfInstalled.Lines.Where(p => p.ToID == step.ID).Count() == 0)
                {
                    firstStepIDList.Add(step.ID);
                }
            }
            if (firstStepIDList.Count == 0)
            {
                errMsg = "流程没有开始步骤";
                return null;
            }
            /*
            else if (firstStepIDList.Count > 1)
            {
                errMsg = "流程有多个开始步骤";
                return null;
            }

            Guid lastStepID = Guid.Empty;
            foreach (var step in wfInstalled.Steps)
            {
                if (wfInstalled.Lines.Where(p => p.FromID == step.ID).Count() == 0)
                {
                    lastStepID = step.ID;
                    break;
                }
            }
            if (lastStepID == Guid.Empty)
            {
                errMsg = "流程没有结束步骤";
                return null;
            }
            */
            var wf = WorkFlowDal.Instance.Get(wfInstalled.ID);
            if (wf != null)
            {

                wfInstalled.CreateTime = wf.CreateDate;
                wfInstalled.CreateUser = wf.CreateUserID.ToString();
                wfInstalled.DesignJSON = wf.DesignJSON;
                wfInstalled.FirstStepID = firstStepIDList.First();
                wfInstalled.InstallTime = System.DateTime.Now;
                wfInstalled.InstallUser = wf.InstallUserID.ToString();//Platform.Users.CurrentUserID.ToString();
                wfInstalled.RunJSON = jsonString;
                wfInstalled.Status = wf.Status;
            }
            #endregion

            return wfInstalled;
        }

        /// <summary>
        /// 得到一个流程步骤的前面步骤集合
        /// </summary>
        /// <param name="flowID"></param>
        /// <param name="stepID"></param>
        /// <returns></returns>
        public List<Step> GetPrevSteps(Guid flowID, Guid stepID)
        {
            List<Step> stepList = new List<Step>();
            var wfl = WebOS.Dal.WorkFlowDal.Instance.Get(flowID);
            string error = "";
            var wfInstalled = WorkFlowBll.Instance.GetWorkFlowRunModel(wfl.RunJSON, out error);
            if (wfInstalled == null)
            {
                return stepList;
            }
            var lines = wfInstalled.Lines.Where(p => p.ToID == stepID);
            foreach (var line in lines)
            {
                var step = wfInstalled.Steps.Where(p => p.ID == line.FromID);
                if (step.Count() > 0)
                {
                    stepList.Add(step.First());
                }
            }
            return stepList;
        }
        /// <summary>
        /// 得到一个流程当前步骤的后续步骤集合
        /// </summary>
        /// <param name="flowID"></param>
        /// <param name="stepID"></param>
        /// <returns></returns>
        public List<Step> GetNextSteps(Guid flowID, Guid stepID)
        {
            List<Step> stepList = new List<Step>();
            var wfl = WebOS.Dal.WorkFlowDal.Instance.Get(flowID);
            string error = "";
            var wfInstalled = WorkFlowBll.Instance.GetWorkFlowRunModel(wfl.RunJSON, out error);
            if (wfInstalled == null)
            {
                return stepList;
            }
            var lines = wfInstalled.Lines.Where(p => p.FromID == stepID);
            foreach (var line in lines)
            {
                var step = wfInstalled.Steps.Where(p => p.ID == line.ToID);
                if (step.Count() > 0)
                {
                    stepList.Add(step.First());
                }
            }
            return stepList;
        }
    }
}
